// app/schedule/process_plugin_data.js
'use strict';

const Subscription = require('egg').Subscription;

class ProcessPluginData extends Subscription {
  // 通过 schedule 属性来设置定时任务的执行间隔等配置
  static get schedule() {
    return {
      interval: '1m', // 1分钟间隔
      type: 'all', // 指定所有的 worker 都需要执行
      immediate: true, // 应用启动后立即执行一次
    };
  }

  // subscribe 是真正定时任务执行时被运行的函数
  async subscribe() {
    const { ctx } = this;
    
    try {
      ctx.logger.info('[Schedule] 开始处理插件数据');
      
      // 获取待处理的数据批次
      const pendingBatches = await ctx.model.PluginDataBatchModel.findAll({
        where: {
          status: 'pending'
        },
        order: [['createdAt', 'ASC']],
        limit: 10 // 每次最多处理10个批次
      });
      
      if (pendingBatches.length === 0) {
        ctx.logger.info('[Schedule] 没有待处理的数据批次');
        return;
      }
      
      ctx.logger.info(`[Schedule] 发现 ${pendingBatches.length} 个待处理批次`);
      
      // 逐个处理批次
      for (const batch of pendingBatches) {
        try {
          // 安全检查：验证批次数据
          if (!batch.batchId || batch.batchId.length > 100) {
            ctx.logger.warn(`[Schedule] 批次ID格式错误，跳过处理: ${batch.batchId}`);
            continue;
          }
          
          // 获取批次对应的数据项
          const dataItems = await ctx.model.PluginDataItemModel.findAll({
            where: {
              batchId: batch.batchId
            },
            limit: 1000 // 限制单次处理数据量
          });
          
          if (dataItems.length === 0) {
            ctx.logger.warn(`[Schedule] 批次 ${batch.batchId} 没有数据项，标记为完成`);
            await batch.update({
              status: 'completed',
              processedCount: 0,
              completedAt: new Date()
            });
            continue;
          }
          
          ctx.logger.info(`[Schedule] 开始处理批次 ${batch.batchId}，包含 ${dataItems.length} 条数据`);
          
          // 按数据类型分类处理
          const categorizedItems = {};
          for (const item of dataItems) {
            const category = item.category || 'unknown';
            if (!categorizedItems[category]) {
              categorizedItems[category] = [];
            }
            categorizedItems[category].push(item);
          }
          
          // 处理各类数据
          let processedCount = 0;
          let failedCount = 0;
          
          for (const [category, items] of Object.entries(categorizedItems)) {
            try {
              ctx.logger.info(`[Schedule] 处理 ${items.length} 条 ${category} 数据`);
              
              // 根据数据类型调用相应的处理方法
              if (category === 'bank') {
                for (const item of items) {
                  const result = await ctx.service.pluginDataService.processBankData(item);
                  if (result && result.success) {
                    await item.update({
                      status: 'processed',
                      processedAt: new Date()
                    });
                    processedCount++;
                  } else {
                    await item.update({
                      status: 'failed',
                      errorMessage: result ? result.error : '处理失败',
                      processedAt: new Date()
                    });
                    failedCount++;
                  }
                }
              } else if (category === 'sales_order' || category === 'purchase_order') {
                // 订单数据处理
                for (const item of items) {
                  await item.update({
                    status: 'processed',
                    processedAt: new Date()
                  });
                  processedCount++;
                }
              } else if (category === 'invoice' || category === 'incoming_invoice' || category === 'outgoing_invoice') {
                // 发票数据处理
                for (const item of items) {
                  // 这里应该调用具体的发票处理服务
                  await item.update({
                    status: 'processed',
                    processedAt: new Date()
                  });
                  processedCount++;
                }
              } else {
                // 其他类型数据
                for (const item of items) {
                  await item.update({
                    status: 'processed',
                    processedAt: new Date()
                  });
                  processedCount++;
                }
              }
            } catch (categoryError) {
              ctx.logger.error(`[Schedule] 处理 ${category} 数据失败:`, categoryError);
              failedCount += items.length;
            }
          }
          
          // 更新批次状态
          await batch.update({
            status: 'completed',
            processedCount: processedCount,
            failedCount: failedCount,
            completedAt: new Date()
          });
          
          ctx.logger.info(`[Schedule] 批次 ${batch.batchId} 处理完成 - 成功: ${processedCount}, 失败: ${failedCount}`);
        } catch (batchError) {
          ctx.logger.error(`[Schedule] 处理批次 ${batch.batchId} 失败:`, batchError);
          
          // 标记批次为失败
          await batch.update({
            status: 'failed',
            errorMessage: batchError.message,
            completedAt: new Date()
          });
        }
      }
    } catch (error) {
      ctx.logger.error('[Schedule] 处理插件数据定时任务失败:', error);
    }
  }
}

module.exports = ProcessPluginData;